using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.ComponentModel;
using C4F.DevKit.WebServices.Datasets;

namespace C4F.DevKit.WebServices
{
    /// <summary>
    /// Exposes the functionality to get RSS feed items for requested URL
    /// </summary>
    [ToolboxItem(true)]
    public class Rss : C4FWebServicesBase
    {
        #region Public functions

        /// <summary>
        /// Gets Rss feed items for requested URL.
        /// </summary>
        /// <param name="feedUrl">Url of the RSS feed</param>
        /// <param name="publishedAfterDate">Optional parameter. If specified, only items published after 
        /// this date will be returned</param>
        /// <returns>List of feed items matching input criteria</returns>
        /// <exception cref="ArgumentNullException">The feedUrl is not specified</exception>
        public List<RssFeedData> GetRssFeed(string feedUrl, DateTime? publishedAfterDate)
        {
            if (string.IsNullOrEmpty(feedUrl))
                throw new ArgumentNullException("feedUrl");

            string responseData = base.GetQueryResponse(feedUrl);
            XmlDocument rssFeedDocument = new XmlDocument();
            rssFeedDocument.LoadXml(responseData);

            // Retrieve all item nodes
            XmlNodeList rssFeedItems = rssFeedDocument.DocumentElement.SelectSingleNode("channel").SelectNodes("item");
            RssFeedData feedData;
            List<RssFeedData> feedItems = new List<RssFeedData>();

            foreach (XmlNode rssFeedItemNode in rssFeedItems)
            {
                feedData = new RssFeedData();
                feedData.Title = rssFeedItemNode.SelectSingleNode("title").InnerText;
                feedData.Url = rssFeedItemNode.SelectSingleNode("link").InnerText;
                feedData.Description = rssFeedItemNode.SelectSingleNode("description").InnerText;
                if (rssFeedItemNode.SelectSingleNode("pubDate") != null)
                    feedData.PublishedOnDate = DateTime.Parse(rssFeedItemNode.SelectSingleNode("pubDate").InnerText,
                                                                null, System.Globalization.DateTimeStyles.RoundtripKind);
                if (rssFeedItemNode.SelectSingleNode("author") != null)
                    feedData.Author = rssFeedItemNode.SelectSingleNode("author").InnerText;

                if (!publishedAfterDate.HasValue || feedData.PublishedOnDate > publishedAfterDate.Value)
                    feedItems.Add(feedData);
            }

            return feedItems;
        }

        /// <summary>
        /// Gets Rss feed items for requested URL.
        /// </summary>
        /// <param name="feedUrl">Url of the RSS feed</param>
        /// <param name="publishedAfterDate">Optional parameter. If specified, only items published after 
        /// this date will be returned</param>
        /// <returns>Dataset containing list of feed items matching input criteria</returns>
        /// <exception cref="ArgumentNullException">The feedUrl is not specified</exception>
        public DS_Rss GetRssFeed_DS(string feedUrl, DateTime? publishedAfterDate)
        {
            List<RssFeedData> feedItems = GetRssFeed(feedUrl, publishedAfterDate);
            DS_Rss dataset = new DS_Rss();
            foreach (RssFeedData feedItem in feedItems)
            {
                dataset.RssFeedData.AddRssFeedDataRow(feedItem.Title, feedItem.Url, feedItem.Description,
                    feedItem.PublishedOnDate, feedItem.Author);
            }
            return dataset;
        }
        #endregion
    }

    /// <summary>
    /// Represents an RSS feed item
    /// </summary>
    public class RssFeedData
    {
        #region Private Members
        /// <summary>
        /// Title of the item
        /// </summary>
        private string title;
        /// <summary>
        /// URL to item details
        /// </summary>
        private string url;
        /// <summary>
        /// Description of the item
        /// </summary>
        private string description;
        /// <summary>
        /// Date and time when published
        /// </summary>
        private DateTime publishedOnDate;
        /// <summary>
        /// Author name
        /// </summary>
        private string author;
        #endregion

        #region Public Properties
        /// <summary>
        /// Title of the item
        /// </summary>
        public string Title
        {
            get { return this.title; }
            set { this.title = value; }
        }
        /// <summary>
        /// URL to item details
        /// </summary>
        public string Url
        {
            get { return this.url; }
            set { this.url = value; }
        }
        /// <summary>
        /// Description of the item
        /// </summary>
        public string Description
        {
            get { return this.description; }
            set { this.description = value; }
        }
        /// <summary>
        /// Date and time when published
        /// </summary>
        public DateTime PublishedOnDate
        {
            get { return this.publishedOnDate; }
            set { this.publishedOnDate = value; }
        }
        /// <summary>
        /// Name of the author
        /// </summary>
        public string Author
        {
            get { return this.author; }
            set { this.author = value; }
        }
        #endregion
    }
}